﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.UI;
using Camc.Quality.Common;
using Camc.Quality.DataDictionary;
using Camc.Quality.Materials.Dto;
using Camc.Quality.QualityPlatform;
using Camc.Quality.StoreManagement.Dto;
using Camc.Quality.StoreManagement.SoreModel.Dto;
using Camc.Quality.StoreManagement.StoragePut;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Camc.Quality.StoreManagement.StoreModel
{
    public  class StoreAppService : QualityAppServiceBase
    {
        private readonly IRepository<StoreContent, Guid> _storeContentrepository;
        private readonly IRepository<Sys_Code, Guid> _sysCodeRepository;
        public readonly IRepository<StoreStockContent, Guid> _storeStockContentRepository;
        public readonly IRepository<StorePutContent, Guid> _storePutContentRepository;
        //public readonly CodeFormatDescAppService _codeFormatDescAppServiceRepsitory;
        public StoreAppService(
            IRepository<StoreContent, Guid> storeContentrepository, 
            IRepository<Sys_Code, Guid> sysCodeRepository, 
            IRepository<StoreStockContent, Guid> storeStockContentRepository, 
            IRepository<StorePutContent, Guid> storePutContentRepository
            ) 
        {
            _storeContentrepository = storeContentrepository;
            _sysCodeRepository = sysCodeRepository; 
            _storeStockContentRepository = storeStockContentRepository;
            _storePutContentRepository = storePutContentRepository;

        }
        /// <summary>
        /// 查询仓库信息
        /// </summary>
        /// <returns></returns>
        public async Task<PagedResultDto<StoreContentDto>> GetStoreContentList(StoreContentInput input) 
        {
            var sysCodeList = _sysCodeRepository.GetAll();
            var queryStoreDatas = from storeData in _storeContentrepository.GetAll()
                                  join sysCode in _sysCodeRepository.GetAll().Where(t => t.Description == "仓库类型") on storeData.StroeTypeId equals sysCode.Id
                                  into joinDc
                                  from dc in joinDc.DefaultIfEmpty()
                                  select new StoreContentDto
                                  {
                                      Id = storeData.Id,
                                      StroeNo = storeData.StroeNo,
                                      StroeName = storeData.StroeName,
                                      StroeTypeName = sysCodeList.FirstOrDefault(s=>s.Id == storeData.StroeTypeId).Description,
                                      StroeTypeId = storeData.StroeTypeId,
                                      StoreUse = (int)storeData.StoreUse,
                                      StoreUseName = EnumTransfer.GetEnumName<StoreEnum.StoreIsUse>((int)storeData.StoreUse),
                                      Remark = storeData.Remark
                                  };
            var count = queryStoreDatas.Count();
            queryStoreDatas = queryStoreDatas.OrderByDescending(e => e.CreationTime).PageBy(input);
            if (queryStoreDatas != null)
            { 
                return new PagedResultDto<StoreContentDto>(count, queryStoreDatas.ToList());
            }
            return new PagedResultDto<StoreContentDto>();
        }
        public async Task AddOrUpdate(StoreContentDto  storeContentDto) 
        {
            if (storeContentDto.Id == Guid.Empty)
            {
                CreateStoreContent(storeContentDto);
            }
            else 
            {
                await UpdateStoreContent(storeContentDto);
            }
        }
        /// <summary>
        /// 更新仓库信息
        /// </summary>
        /// <param name="storeContent"></param>
        /// <returns></returns>
        private async Task UpdateStoreContent(StoreContentDto storeContent)
        {
            //判断仓库是否已被使用 如果已使用 不能被编辑
            var queryStoreContent =  _storeContentrepository.FirstOrDefaultAsync(t => t.Id == storeContent.Id).Result;
            if (queryStoreContent != null )
            {
                if ((int)queryStoreContent.StoreUse == 1 && storeContent.StoreUse == 1)
                {
                    throw new UserFriendlyException("仓库已使用不能被编辑");
                }
                var stoeName = _storeContentrepository.FirstOrDefault(s => s.Id != storeContent.Id && s.StroeName == storeContent.StroeName);
                if (stoeName == null)
                {
                    queryStoreContent.StroeName = storeContent.StroeName;
                    queryStoreContent.StroeTypeId = storeContent.StroeTypeId;
                    queryStoreContent.StoreUse = (StoreEnum.StoreIsUse)storeContent.StoreUse;
                    queryStoreContent.Remark = storeContent.Remark;
                    //var stroeContentNew = ObjectMapper.Map(storeContent, queryStoreContent);
                    await _storeContentrepository.UpdateAsync(queryStoreContent);
                    var storePutContent = _storePutContentRepository.GetAll().Where(s => s.StoreId == storeContent.Id && s.StroeName != storeContent.StroeName);
                    var query = storePutContent.ToList();
                    //更新合格证表里的仓库名
                    for (var i = 0; i < storePutContent.Count(); i++)
                    {
                        var querystorePutContent = _storePutContentRepository.FirstOrDefault(s => s.Id == query[i].Id);
                        querystorePutContent.StroeName = storeContent.StroeName;
                        await _storePutContentRepository.UpdateAsync(querystorePutContent);
                    }
                    var storeStockContent = _storeStockContentRepository.GetAll().Where(s => s.StoreId == storeContent.Id && s.StroeName != storeContent.StroeName);
                    var queryData = storeStockContent.ToList();
                    //更新仓库详细信息表里的仓库名
                    for (var i = 0; i < storeStockContent.Count(); i++)
                    {
                        var querystoreStockContent = _storeStockContentRepository.FirstOrDefault(s => s.Id == queryData[i].Id);
                        querystoreStockContent.StroeName = storeContent.StroeName;
                        await _storeStockContentRepository.UpdateAsync(querystoreStockContent);
                    }
                }
                else 
                {
                    throw new UserFriendlyException("仓库名字不能重复");
                }
            }
        }
        /// <summary>
        /// 增加仓库信息
        /// </summary>
        /// <param name="storeContent"></param>
        private void CreateStoreContent(StoreContentDto storeContent)
        {
            var stoeName = _storeContentrepository.FirstOrDefault(s=>s.StroeName == storeContent.StroeName);
            if (stoeName == null)
            {
                var storeNoList = from sc in _storeContentrepository.GetAll()
                                  select new StoreContentDto
                                  {
                                      StroeNum = Convert.ToInt32(sc.StroeNo)
                                  };
                int storeNo = 0;
                if (storeNoList != null)
                {
                    storeNo = storeNoList.Select(s => s.StroeNum).ToArray().Max();
                }
                StoreContent storeContentDto = new StoreContent
                {
                    Id = Guid.NewGuid(),
                    StroeNo = (storeNo + 1).ToString("000"),
                    StroeName = storeContent.StroeName,
                    StroeTypeId = storeContent.StroeTypeId,
                    StoreUse = (StoreEnum.StoreIsUse)storeContent.StoreUse,
                    Remark = storeContent.Remark
                };
                _storeContentrepository.InsertAsync(storeContentDto);
            }
            else
            {
                throw new UserFriendlyException("仓库名字不能重复");
            }
        }
        /// <summary>
        /// 删除仓库
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ResultMessage> DeleteStoreContent(Guid id) 
        {
            ResultMessage resultMessage = new ResultMessage();
            try
            {
                var queryStoreContent = _storeContentrepository.FirstOrDefaultAsync(t => t.Id == id).Result;
                //判断仓库是否有数据存在，如果有不能删除
                if (queryStoreContent != null)
                {
                    var storeStockContent = _storeStockContentRepository.GetAll().Where(s => s.StoreId == queryStoreContent.Id);
                    if (storeStockContent.Count() > 0)
                    {
                        resultMessage.code = 1;
                        resultMessage.Message = "此仓库已有业务发生，不能删除！如不再需要此仓库，请编辑仓库选择停用！";
                        return resultMessage;
                        //throw new UserFriendlyException("此仓库已有业务发生，不能删除！如不再需要此仓库，请编辑仓库选择停用！");
                    }
                    await _storeContentrepository.DeleteAsync(s => s.Id == id);
                }
                resultMessage.code = 0;
                return resultMessage;
            }
            catch (Exception ex)
            {
                resultMessage.code = 1;
                resultMessage.Message = ex.Message;
                return resultMessage;
            }
        }
        /// <summary>
        /// 仓库类型下拉列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<MaterialsOtherDto>> GetStoreTypeList()
        {
            var queryCode = from sc in _sysCodeRepository.GetAll().Where(s => s.IsUsed == 1)
                            join scc in _sysCodeRepository.GetAll()
                            on sc.PPtr equals scc.Id
                            where scc.Description == "仓库类型"
                            select new MaterialsOtherDto
                            {
                                label = sc.Description,
                                value = sc.Id
                            };
            if (queryCode.Count() > 0)
            {
                return queryCode.ToList();
            }
            return new List<MaterialsOtherDto>();
        }

    }
}
